package com.zjl.SpringBoot.第01章_基础;

import lombok.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 *  @ConfigurationProperties(prefix = "pig2") 指定次Bean 的属性的值在 properties 文件中可以注入
 *  放在 类上 需要和  @Component 注解配合，将此类进入配置，否则不配置
 *  放在 方法上上 需要和  @Component 和 @Bean 注解配合，否则不配置
 *  可与用  @EnableConfigurationProperties(value = {Sheep.class})
 *  代替  @Component 注解，常用于第三方的包放入了  @ConfigurationProperties 没放  @Component 时使用
 *
 *
 *
 */
@Configuration
@SpringBootApplication(
        scanBasePackages = {"com.zjl.SpringBoot.第01章_基础"}//默认就是此包 就是 run中类的 package
)
@EnableConfigurationProperties(value = {Sheep.class})//快速注解注释  可以用于
public class F3_属性绑定Config {

    @Bean(name = "pig3")
    //注入  不加 @Component 的话 @ConfigurationProperties 这个不会生效   @Configuration 包含了 @Component
    @ConfigurationProperties(prefix = "pig2")//可放在类上
    public Pig pig2(){//名字不可重复  优先 @Bean 注解   再方法名
        return new Pig();
    }

    public static void main(String[] args) {
        System.setProperty("spring.profiles.active","属性绑定");//  同理 --spring.profiles.active=属性绑定
        ConfigurableApplicationContext run = SpringApplication.run(SpringBoot的自动配置完整流程.class, args);
        System.out.println("*********************");
        Map<String, Pig> beansOfType = run.getBeansOfType(Pig.class);
        //存在汉语乱码   因为 File -> Settings -> Editor -> File Encodings ->
        // 都改成UTF-8 和  口 Transparent native-to-ascii conversion    勾选上
        System.out.println(beansOfType);
        System.out.println("********复杂的*************");
        Person person = run.getBean(Person.class);
        System.out.println(person);
        System.out.println("********@EnableConfigurationProperties*************");
        Sheep sheep = run.getBean(Sheep.class);
        System.out.println(sheep);
    }

}
@ToString//toString方法
@Data//get set方法
@NoArgsConstructor//无参构造器
@AllArgsConstructor//全参构造器
@EqualsAndHashCode//EqualsAndHashCode方法
@ConfigurationProperties(prefix = "pig")//可放在方法上  与 @Bean同理
@Component//注入  不加 @Component 的话 @ConfigurationProperties 这个不会生效
class Pig{
    private Long id;
    private String name;
    private Double weight;
    private Integer age;
}
@ToString//toString方法
@Data//get set方法
@NoArgsConstructor//无参构造器
@AllArgsConstructor//全参构造器
@EqualsAndHashCode//EqualsAndHashCode方法
@ConfigurationProperties(prefix = "sheep")//可放在方法上  与 @Bean同理
class Sheep{
    private Long id;
    private String name;
    private Integer age;
}
@Component//表示这是个组件
@AllArgsConstructor
@NoArgsConstructor
@Data
@ToString
@ConfigurationProperties(prefix = "person")//核心配置文件绑定
class Person {

    private String userName;
    private String test;
    private Boolean boss;
    private LocalDate birth;
    private Integer age;
    private Pig pig;
    private String[] interests;
    private List<String> animal;
    private Map<String, Object> score;
    private Set<Double> salary;
    private Map<String, List<Pig>> allPigs;

    public Person(String[] interests, List<String> animal, Map<String, Object> score, Set<Double> salary) {
        this.interests = interests;
        this.animal = animal;
        this.score = score;
        this.salary = salary;
    }
}